#include "box2d_internal.hpp"

#include <Box2D/Dynamics/b2Body.h>

int box2d_core_world_tag;

LUAF(create_world)
{
	void* mem = lua_newuserdata(L, sizeof(LuaWorld));
	
	LuaWorld* self = new (mem) LuaWorld();
	prepare_object(L, &box2d_core_world_tag); // self -- self

	return 1;
}

LUAF(clone_world)
{
	auto& world = check_world(L, 1);

	void* mem = lua_newuserdata(L, sizeof(LuaWorld));
	
	LuaWorld* self = new (mem) LuaWorld(world);
	prepare_object(L, &box2d_core_world_tag); // self -- self

	return 1;
}

LUAF(world_destroy)
{
	auto& world = check_world(L, 1);

	luaext_setuserdatatag(L, 1, 0); // Make sure the object cannot be used anymore

	world.~LuaWorld();
	return 0;
}

LUAF(create_body)
{
	auto& world = check_world(L, 1);

	float32 x = float32(luaL_checknumber(L, 2));
	float32 y = float32(luaL_checknumber(L, 3));
	int isStatic = lua_toboolean(L, 4);

	unsigned id = world.nextBodyId++;

	b2BodyDef def;
	def.userData = (void*)id;
	def.position = b2Vec2(x, y);
	def.linearDamping = 0.f;
	def.angularDamping = 0.f;
	def.type = isStatic ? b2_staticBody : b2_dynamicBody;
	
	b2Body* body = world.CreateBody(&def);

	world.aliveBodies.insert(NumberedIndex<void*>(id, body));

	lua_pushinteger(L, id);
	return 1;
}

LUAF(world_step)
{
	auto& world = check_world(L, 1);

	float32 timeStep = float32(luaL_checknumber(L, 2));

	world.Step(timeStep, 10, 10);
	world.ClearForces();
	return 0;
}